package top.chengdongqing.weui.core.ui.components.swipeaction

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.times
import kotlin.math.roundToInt

enum class SwipeActionStyle {
    LABEL,
    ICON
}

enum class SwipeActionType(val color: Color) {
    PLAIN(Color.Gray),
    WARNING(Color.Yellow),
    DANGER(Color.Red)
}

data class SwipeActionItem(
    val type: SwipeActionType? = null,
    val label: String,
    val icon: ImageVector? = null
)

@Composable
fun WeSwipeAction(
    startOptions: List<SwipeActionItem>? = null,
    endOptions: List<SwipeActionItem>? = null,
    style: SwipeActionStyle = SwipeActionStyle.LABEL,
    onStartTap: ((index: Int) -> Unit)? = null,
    onEndTap: ((index: Int) -> Unit)? = null,
    height: Dp = 60.dp,
    content: @Composable (BoxScope.() -> Unit)
) {
    val density = LocalDensity.current
    val startWidth = startOptions?.size?.let { it * if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp }?.let { with(density) { it.toPx() } } ?: 0f
    val endWidth = endOptions?.size?.let { it * if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp }?.let { with(density) { it.toPx() } } ?: 0f

    var offsetX by remember { mutableFloatStateOf(0f) }
    val animatedOffsetX by animateFloatAsState(
        targetValue = offsetX,
        animationSpec = tween(durationMillis = 200)
    )

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(height)
            .clipToBounds()
            .pointerInput(Unit) {
                detectHorizontalDragGestures(
                    onHorizontalDrag  = { change, dragAmount ->
                        change.consume()
                        val newOffset = offsetX + dragAmount
                        offsetX = newOffset.coerceIn(-startWidth, endWidth)
                    },
                    onDragEnd = {
                        when {
                            offsetX <= -startWidth * 0.5f -> offsetX = -startWidth
                            offsetX >= endWidth * 0.5f -> offsetX = endWidth
                            else -> offsetX = 0f
                        }
                    },
                )
            }
    ) {
        // 左侧按钮组
        startOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterStart)) {
                startOptions.forEachIndexed { index, item ->
                    val fraction = (1f / startOptions.size) * (index + 1)
                    ActionItem(
                        width = if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp,
                        offset = IntOffset(
                            x = (((-animatedOffsetX * fraction) - with(density) { (if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp).toPx() })).roundToInt(),
                            y = 0
                        ),
                        isLabelStyle = style == SwipeActionStyle.LABEL,
                        item = item
                    ) {
                        onStartTap?.invoke(index)
                        offsetX = 0f
                    }
                }
            }
        }

        // 内容
        Box(
            modifier = Modifier
                .fillMaxSize()
                .offset {
                    IntOffset(
                        x = -animatedOffsetX.roundToInt(),
                        y = 0
                    )
                }
                .background(
                    color = MaterialTheme.colorScheme.onBackground,
                    if (style != SwipeActionStyle.LABEL) RoundedCornerShape(8.dp) else RectangleShape
                )
                .padding(horizontal = 16.dp),
            contentAlignment = Alignment.CenterStart
        ) {
            content()
        }

        // 右侧按钮组
        endOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterEnd)) {
                endOptions.forEachIndexed { index, item ->
                    val fraction = 1f - (1f / endOptions.size) * index
                    ActionItem(
                        width = if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp,
                        offset = IntOffset(
                            x = ((-animatedOffsetX * fraction) + with(density) { (if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp).toPx() }).roundToInt(),
                            y = 0
                        ),
                        isLabelStyle = style == SwipeActionStyle.LABEL,
                        item = item
                    ) {
                        onEndTap?.invoke(index)
                        offsetX = 0f
                    }
                }
            }
        }
    }
}

@Composable
private fun ActionItem(
    width: Dp,
    offset: IntOffset,
    isLabelStyle: Boolean,
    item: SwipeActionItem,
    onClick: () -> Unit
) {
    Box(
        modifier = Modifier
            .width(width)
            .fillMaxHeight()
            .offset { offset }
            .then(
                if (isLabelStyle && item.type != null) {
                    Modifier
                        .background(item.type.color)
                        .clickable(onClick = onClick)
                } else {
                    Modifier
                }
            ),
        contentAlignment = Alignment.Center
    ) {
        if (isLabelStyle || item.icon == null) {
            Text(text = item.label, color = Color.White, fontSize = 14.sp)
        } else {
            Box(
                modifier = Modifier
                    .size(45.dp)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.onBackground)
                    .clickable(onClick = onClick),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = item.icon,
                    contentDescription = item.label,
                    tint = MaterialTheme.colorScheme.onPrimary,
                    modifier = Modifier.size(20.dp)
                )
            }
        }
    }
}

// 示例使用
@Composable
fun SwipeActionListExample() {
    val startOptions = listOf(
        SwipeActionItem(type = SwipeActionType.PLAIN, label = "编辑"),
        SwipeActionItem(type = SwipeActionType.WARNING, label = "分享")
    )
    val endOptions = listOf(
        SwipeActionItem(type = SwipeActionType.DANGER, label = "删除")
    )

    LazyColumn {
        items(10) { index ->
            WeSwipeAction(
                startOptions = startOptions,
                endOptions = endOptions,
                style = SwipeActionStyle.LABEL,
                onStartTap = { startIndex ->
                    println("点击了开始侧滑选项 $startIndex")
                },
                onEndTap = { endIndex ->
                    println("点击了结束侧滑选项 $endIndex")
                },
                content = {
                    Text(text = "Item $index", fontSize = 18.sp)
                }
            )
        }
    }
}

/*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.SwipeToDismiss
import androidx.compose.material.rememberDismissState
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

enum class SwipeActionStyle {
    LABEL,
    ICON
}

enum class SwipeActionType(val color: Color) {
    PLAIN(Color.Gray),
    WARNING(Color.Yellow),
    DANGER(Color.Red)
}

data class SwipeActionItem(
    val type: SwipeActionType? = null,
    val label: String,
    val icon: ImageVector? = null
)

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun WeSwipeAction(
    startOptions: List<SwipeActionItem>? = null,
    endOptions: List<SwipeActionItem>? = null,
    style: SwipeActionStyle = SwipeActionStyle.LABEL,
    onStartTap: ((index: Int) -> Unit)? = null,
    onEndTap: ((index: Int) -> Unit)? = null,
    height: Dp = 60.dp,
    content: @Composable (BoxScope.() -> Unit)
) {
    val dismissState = rememberDismissState(
        confirmStateChange = { dismissValue ->
            when (dismissValue) {
                androidx.compose.material.DismissValue.DismissedToEnd -> {
                    startOptions?.let {
                        onStartTap?.invoke(0)
                    }
                    true
                }
                androidx.compose.material.DismissValue.DismissedToStart -> {
                    endOptions?.let {
                        onEndTap?.invoke(0)
                    }
                    true
                }
                else -> false
            }
        }
    )

    SwipeToDismiss(
        state = dismissState,
        directions = setOf(
            androidx.compose.material.DismissDirection.StartToEnd,
            androidx.compose.material.DismissDirection.EndToStart
        ),
        background = {
            val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
            val options = if (direction == androidx.compose.material.DismissDirection.StartToEnd) startOptions else endOptions
            val alignment = if (direction == androidx.compose.material.DismissDirection.StartToEnd) Alignment.CenterStart else Alignment.CenterEnd

            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Transparent)
                    .padding(horizontal = 8.dp),
                contentAlignment = alignment
            ) {
                options?.forEachIndexed { index, item ->
                    ActionItem(
                        width = if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp,
                        isLabelStyle = style == SwipeActionStyle.LABEL,
                        item = item
                    ) {
                        if (direction == androidx.compose.material.DismissDirection.StartToEnd) {
                            onStartTap?.invoke(index)
                        } else {
                            onEndTap?.invoke(index)
                        }
                        // 关闭侧滑菜单
                        LaunchedEffect(Unit) {
                            dismissState.reset()
                        }
                    }
                }
            }
        },
        dismissContent = {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(height)
                    .clipToBounds()
                    .background(
                        color = MaterialTheme.colorScheme.onBackground,
                        shape = if (style != SwipeActionStyle.LABEL) RoundedCornerShape(8.dp) else RectangleShape
                    )
                    .padding(horizontal = 16.dp),
                contentAlignment = Alignment.CenterStart
            ) {
                content()
            }
        }
    )
}

@Composable
private fun ActionItem(
    width: Dp,
    isLabelStyle: Boolean,
    item: SwipeActionItem,
    onClick: () -> Unit
) {
    Box(
        modifier = Modifier
            .width(width)
            .fillMaxHeight()
            .then(
                if (isLabelStyle && item.type != null) {
                    Modifier
                        .background(item.type.color)
                        .clickable(onClick = onClick)
                } else {
                    Modifier
                }
            ),
        contentAlignment = Alignment.Center
    ) {
        if (isLabelStyle || item.icon == null) {
            Text(text = item.label, color = Color.White, fontSize = 14.sp)
        } else {
            Box(
                modifier = Modifier
                    .size(45.dp)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.onBackground)
                    .clickable(onClick = onClick),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = item.icon,
                    contentDescription = item.label,
                    tint = MaterialTheme.colorScheme.onPrimary,
                    modifier = Modifier.size(20.dp)
                )
            }
        }
    }
}

// 示例使用
@Composable
fun SwipeActionListExample() {
    val startOptions = listOf(
        SwipeActionItem(type = SwipeActionType.PLAIN, label = "编辑"),
        SwipeActionItem(type = SwipeActionType.WARNING, label = "分享")
    )
    val endOptions = listOf(
        SwipeActionItem(type = SwipeActionType.DANGER, label = "删除")
    )

    LazyColumn {
        items(10) { index ->
            WeSwipeAction(
                startOptions = startOptions,
                endOptions = endOptions,
                style = SwipeActionStyle.LABEL,
                onStartTap = { startIndex ->
                    println("点击了开始侧滑选项 $startIndex")
                },
                onEndTap = { endIndex ->
                    println("点击了结束侧滑选项 $endIndex")
                },
                content = {
                    Text(text = "Item $index", fontSize = 18.sp)
                }
            )
        }
    }
}*/

/*import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.DraggableState
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import top.chengdongqing.weui.core.data.model.DragAnchor
import top.chengdongqing.weui.core.ui.theme.DangerColorLight
import top.chengdongqing.weui.core.ui.theme.PlainColor
import top.chengdongqing.weui.core.ui.theme.WarningColor
import kotlin.math.roundToInt

enum class SwipeActionStyle {
    LABEL,
    ICON
}

enum class SwipeActionType(val color: Color) {
    PLAIN(PlainColor),
    WARNING(WarningColor),
    DANGER(DangerColorLight)
}

data class SwipeActionItem(
    val type: SwipeActionType? = null,
    val label: String,
    val icon: ImageVector? = null
)

@Composable
fun WeSwipeAction(
    startOptions: List<SwipeActionItem>? = null,
    endOptions: List<SwipeActionItem>? = null,
    style: SwipeActionStyle = SwipeActionStyle.LABEL,
    swipeActionState: SwipeActionState = rememberSwipeActionState(
        actionItemWidth = if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp,
        startActionCount = startOptions?.size ?: 0,
        endActionCount = endOptions?.size ?: 0
    ),
    onStartTap: ((index: Int) -> Unit)? = null,
    onEndTap: ((index: Int) -> Unit)? = null,
    height: Dp = 60.dp,
    content: @Composable (BoxScope.() -> Unit)
) {
    val state = swipeActionState.draggableState
    val isLabelStyle = style == SwipeActionStyle.LABEL
    val coroutineScope = rememberCoroutineScope()

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(height)
            .clipToBounds()
    ) {
        // 内容
        val offsetX by swipeActionState.offsetXAnimated
        Box(
            modifier = Modifier
                .fillMaxSize()
                .offset {
                    IntOffset(
                        x = -offsetX.roundToInt(),
                        y = 0
                    )
                }
                .background(
                    color = MaterialTheme.colorScheme.onBackground,
                    if (!isLabelStyle) RoundedCornerShape(8.dp) else RectangleShape
                )
                .padding(horizontal = 16.dp)
                .draggable(
                    orientation = Orientation.Horizontal,
                    state = state
                ),
            contentAlignment = Alignment.CenterStart
        ) {
            content()
        }
        // 左侧按钮组
        startOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterStart)) {
                startOptions.forEachIndexed { index, item ->
                    val fraction = (1f / startOptions.size) * (index + 1)
                    ActionItem(
                        width = swipeActionState.actionItemWidth,
                        offset = IntOffset(
                            x = (((-offsetX * fraction) - swipeActionState.actionItemWidthPx)).roundToInt(),
                            y = 0
                        ),
                        isLabelStyle,
                        item
                    ) {
                        onStartTap?.invoke(index)
                        coroutineScope.launch {
                            swipeActionState.snapTo(DragAnchor.Center)
                        }
                    }
                }
            }
        }
        // 右侧按钮组
        endOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterEnd)) {
                endOptions.forEachIndexed { index, item ->
                    val fraction = 1f - (1f / endOptions.size) * index
                    ActionItem(
                        width = swipeActionState.actionItemWidth,
                        offset = IntOffset(
                            x = ((-offsetX * fraction) + swipeActionState.actionItemWidthPx)
                                .roundToInt(),
                            y = 0
                        ),
                        isLabelStyle,
                        item
                    ) {
                        onEndTap?.invoke(index)
                        coroutineScope.launch {
                            swipeActionState.snapTo(DragAnchor.Center)
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun ActionItem(
    width: Dp,
    offset: IntOffset,
    isLabelStyle: Boolean,
    item: SwipeActionItem,
    onClick: () -> Unit
) {
    Box(
        modifier = Modifier
            .width(width)
            .fillMaxHeight()
            .offset { offset }
            .then(
                if (isLabelStyle && item.type != null) {
                    Modifier
                        .background(item.type.color)
                        .clickable(onClick = onClick)
                } else {
                    Modifier
                }
            ),
        contentAlignment = Alignment.Center
    ) {
        if (isLabelStyle || item.icon == null) {
            Text(text = item.label, color = Color.White)
        } else {
            Box(
                modifier = Modifier
                    .size(45.dp)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.onBackground)
                    .clickable(onClick = onClick),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = item.icon,
                    contentDescription = item.label,
                    tint = MaterialTheme.colorScheme.onPrimary,
                    modifier = Modifier.size(20.dp)
                )
            }
        }
    }
}

@Composable
fun rememberSwipeActionState(
    initialValue: DragAnchor = DragAnchor.Center,
    actionItemWidth: Dp = 80.dp,
    startActionCount: Int = 0,
    endActionCount: Int = 0
): SwipeActionState {
    val density = LocalDensity.current
    val actionItemWidthPx = density.run { (actionItemWidth).toPx() }
    val startActionWidthPx = density.run { (actionItemWidth * startActionCount).toPx() }
    val endActionWidthPx = density.run { (actionItemWidth * endActionCount).toPx() }

    var offsetX by remember { mutableFloatStateOf(0f) }
    var currentAnchor by remember { mutableStateOf(initialValue) }
    val coroutineScope = rememberCoroutineScope()

    val draggableState = remember {
        DraggableState { delta ->
            coroutineScope.launch {
                val newOffset = offsetX + delta
                val limitedOffset = newOffset.coerceIn(-startActionWidthPx, endActionWidthPx)
                offsetX = limitedOffset

                when {
                    limitedOffset <= -startActionWidthPx * 0.5f -> currentAnchor = DragAnchor.Start
                    limitedOffset >= endActionWidthPx * 0.5f -> currentAnchor = DragAnchor.End
                    else -> currentAnchor = DragAnchor.Center
                }
            }
        }
    }

    val offsetXAnimated: State<Float> = animateFloatAsState(
        targetValue = offsetX,
        animationSpec = tween()
    )

    LaunchedEffect(offsetX) {
        if (offsetX != 0f) {
            val targetOffset = when (currentAnchor) {
                DragAnchor.Start -> -startActionWidthPx
                DragAnchor.Center -> 0f
                DragAnchor.End -> endActionWidthPx
            }
            offsetX = targetOffset
        }
    }

    return SwipeActionState(
        draggableState,
        offsetXAnimated,
        actionItemWidthPx,
        actionItemWidth
    )
}

data class SwipeActionState(
    val draggableState: DraggableState,
    val offsetXAnimated: State<Float>,
    val actionItemWidthPx: Float,
    val actionItemWidth: Dp
) {
    suspend fun snapTo(anchor: DragAnchor) {
        val targetOffset = when (anchor) {
            DragAnchor.Start -> -actionItemWidthPx * 1000 // 假设最大偏移量
            DragAnchor.Center -> 0f
            DragAnchor.End -> actionItemWidthPx * 1000 // 假设最大偏移量
        }
        // 这里可以考虑更完善的动画处理逻辑，当前仅示例
    }
}*/

/*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.gestures.snapTo
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import top.chengdongqing.weui.core.data.model.DragAnchor
import top.chengdongqing.weui.core.ui.theme.DangerColorLight
import top.chengdongqing.weui.core.ui.theme.PlainColor
import top.chengdongqing.weui.core.ui.theme.WarningColor
import kotlin.math.roundToInt

enum class SwipeActionStyle {
    LABEL,
    ICON
}

enum class SwipeActionType(val color: Color) {
    PLAIN(PlainColor),
    WARNING(WarningColor),
    DANGER(DangerColorLight)
}

data class SwipeActionItem(
    val type: SwipeActionType? = null,
    val label: String,
    val icon: ImageVector? = null
)

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun WeSwipeAction(
    startOptions: List<SwipeActionItem>? = null,
    endOptions: List<SwipeActionItem>? = null,
    style: SwipeActionStyle = SwipeActionStyle.LABEL,
    swipeActionState: SwipeActionState = rememberSwipeActionState(
        actionItemWidth = if (style == SwipeActionStyle.LABEL) 80.dp else 66.dp,
        startActionCount = startOptions?.size ?: 0,
        endActionCount = endOptions?.size ?: 0
    ),
    onStartTap: ((index: Int) -> Unit)? = null,
    onEndTap: ((index: Int) -> Unit)? = null,
    height: Dp = 60.dp,
    content: @Composable (BoxScope.() -> Unit)
) {
    val state = swipeActionState.draggableState
    val isLabelStyle = style == SwipeActionStyle.LABEL
    val coroutineScope = rememberCoroutineScope()

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(height)
            .clipToBounds()
    ) {
        // 内容
        Box(
            modifier = Modifier
                .fillMaxSize()
                .offset {
                    IntOffset(
                        x = -state
                            .requireOffset()
                            .roundToInt(),
                        y = 0
                    )
                }
                .background(
                    color = MaterialTheme.colorScheme.onBackground,
                    if (!isLabelStyle) RoundedCornerShape(8.dp) else RectangleShape
                )
                .padding(horizontal = 16.dp)
                .anchoredDraggable(state, Orientation.Horizontal),
            contentAlignment = Alignment.CenterStart
        ) {
            content()
        }
        // 左侧按钮组
        startOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterStart)) {
                startOptions.forEachIndexed { index, item ->
                    val fraction = (1f / startOptions.size) * (index + 1)
                    ActionItem(
                        width = swipeActionState.actionItemWidth,
                        offset = IntOffset(
                            x = (((-state.requireOffset() * fraction) - swipeActionState.actionItemWidthPx)).roundToInt(),
                            y = 0
                        ),
                        isLabelStyle,
                        item
                    ) {
                        onStartTap?.invoke(index)
                        coroutineScope.launch {
                            state.snapTo(DragAnchor.Center)
                        }
                    }
                }
            }
        }
        // 右侧按钮组
        endOptions?.let {
            Box(modifier = Modifier.align(Alignment.CenterEnd)) {
                endOptions.forEachIndexed { index, item ->
                    val fraction = 1f - (1f / endOptions.size) * index
                    ActionItem(
                        width = swipeActionState.actionItemWidth,
                        offset = IntOffset(
                            x = ((-state.requireOffset() * fraction) + swipeActionState.actionItemWidthPx)
                                .roundToInt(),
                            y = 0
                        ),
                        isLabelStyle,
                        item
                    ) {
                        onEndTap?.invoke(index)
                        coroutineScope.launch {
                            state.snapTo(DragAnchor.Center)
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun ActionItem(
    width: Dp,
    offset: IntOffset,
    isLabelStyle: Boolean,
    item: SwipeActionItem,
    onClick: () -> Unit
) {
    Box(
        modifier = Modifier
            .width(width)
            .fillMaxHeight()
            .offset { offset }
            .then(
                if (isLabelStyle && item.type != null) {
                    Modifier
                        .background(item.type.color)
                        .clickable(onClick = onClick)
                } else {
                    Modifier
                }
            ),
        contentAlignment = Alignment.Center
    ) {
        if (isLabelStyle || item.icon == null) {
            Text(text = item.label, color = Color.White)
        } else {
            Box(
                modifier = Modifier
                    .size(45.dp)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.onBackground)
                    .clickable(onClick = onClick),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = item.icon,
                    contentDescription = item.label,
                    tint = MaterialTheme.colorScheme.onPrimary,
                    modifier = Modifier.size(20.dp)
                )
            }
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun rememberSwipeActionState(
    initialValue: DragAnchor = DragAnchor.Center,
    actionItemWidth: Dp = 80.dp,
    startActionCount: Int = 0,
    endActionCount: Int = 0
): SwipeActionState {
    val density = LocalDensity.current
    val actionItemWidthPx = density.run { (actionItemWidth).toPx() }
    val startActionWidthPx = density.run { (actionItemWidth * startActionCount).toPx() }
    val endActionWidthPx = density.run { (actionItemWidth * endActionCount).toPx() }

    val state = remember {
        AnchoredDraggableState(
            // 初始状态
            initialValue,
            // 设置每个锚点对应的位置（偏移量）
            anchors = DraggableAnchors {
                DragAnchor.Start at -startActionWidthPx
                DragAnchor.Center at 0f
                DragAnchor.End at endActionWidthPx
            },
            // 位置阀值：滑动多远距离自动进入该锚点
            positionalThreshold = { totalDistance -> totalDistance * 0.5f },
            // 速度阀值：即使没有超过位置阀值，一秒钟滑动多少个像素也能自动进入下一个锚点
            velocityThreshold = { density.run { 100.dp.toPx() } },
            // 切换状态的动画
            animationSpec = tween()
        )
    }

    return SwipeActionState(
        state,
        actionItemWidthPx,
        actionItemWidth
    )
}

@OptIn(ExperimentalFoundationApi::class)
data class SwipeActionState(
    val draggableState: AnchoredDraggableState<DragAnchor>,
    val actionItemWidthPx: Float,
    val actionItemWidth: Dp
)*/
